package cn.mujiankeji.mbrowser.功能.浏览框.webview

import android.annotation.SuppressLint
import android.app.AlertDialog
import android.graphics.Bitmap
import android.net.http.SslError
import android.os.Message
import android.text.InputType
import android.webkit.ClientCertRequest
import android.webkit.HttpAuthHandler
import android.webkit.SslErrorHandler
import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.EditText
import android.widget.LinearLayout
import cn.mujiankeji.mbrowser.功能.浏览框.浏览框加载状态
import cn.mujiankeji.mbrowser.功能.浏览框.浏览框状态
import cn.mujiankeji.mbrowser.工具.mlog
import cn.mujiankeji.mbrowser.工具.操作.地址操作
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.Utils
import kotlinx.coroutines.launch
import 操作.工具类.left
import 操作.工具类.right
import java.io.InputStream

/**
 * 自定义 WebViewClient 实现，处理浏览器导航、资源加载和各种网页事件
 */
open class MWebClient(val state : 浏览框状态): WebViewClient(){

    /**
     * 处理新的 URL 加载请求（Android N 及以上版本）
     * 
     * 当用户点击链接或网页尝试加载新 URL 时调用
     * 返回 true 表示应用自行处理该 URL，返回 false 表示让 WebView 继续加载
     */
    @SuppressLint("RequiresFeature")
    override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest): Boolean {
        return state.加载新的页面(request.url.toString(),request)
    }

    /**
     * 当页面可见性提交时调用
     * 
     * 在页面首次可视化渲染完成时触发
     */
    override fun onPageCommitVisible(view: WebView, url: String) {
        super.onPageCommitVisible(view, url)
    }



    /**
     * 处理新的 URL 加载请求（兼容旧版本 Android）
     * 
     * 功能与上面的 shouldOverrideUrlLoading 类似，但用于旧版本 Android
     */
    @Deprecated("Deprecated in Java")
    override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
        return state.加载新的页面(url?:"",null)
    }

    /**
     * 页面开始加载时调用
     * 
     * 当 WebView 开始加载页面时触发，可用于显示加载进度条等
     */
    override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
        super.onPageStarted(view, url, favicon)
        state.更新加载状态(浏览框加载状态.加载开始)
    }

    /**
     * 处理客户端证书请求
     * 
     * 当网站需要客户端证书进行身份验证时调用
     */
    override fun onReceivedClientCertRequest(view: WebView?, request: ClientCertRequest?) {
        super.onReceivedClientCertRequest(view, request)
    }


    /**
     * 页面加载完成时调用
     * 
     * 当页面完全加载完毕后触发，可用于隐藏加载进度条、执行页面脚本等
     */
    override fun onPageFinished(webView: WebView?, s: String?) {
        state.coroutine?.launch {
            state.注入脚本("checkChange()")
        }
        
        // 减少渲染次数，使用更合理的延时间隔
        val delays = listOf(100L, 500L, 1500L)
        for (delay in delays) {
            webView?.postDelayed({
                (webView as? MWebView)?.强制触发渲染()
            }, delay)
        }
        
        // 页面加载完成后检测是否白屏
        webView?.postDelayed({
            检测并修复白屏(webView)
        }, 1500)
    }
    
    /**
     * 检测并修复白屏问题
     */
    private fun 检测并修复白屏(webView: WebView?) {
        if (webView == null) return
        
        webView.evaluateJavascript("(function(){return document.body && document.body.children.length > 0 ? 'has_content' : 'empty'})()") { result ->
            if (result == "\"empty\"" || result == "null") {
                // 检测到白屏，尝试修复
                mlog("检测到白屏，尝试修复")
                (webView as? MWebView)?.强制触发渲染()
                
                // 如果仍然白屏，尝试重新加载
                webView.postDelayed({
                    webView.evaluateJavascript("(function(){return document.body && document.body.children.length > 0 ? 'has_content' : 'empty'})()") { result2 ->
                        if (result2 == "\"empty\"" || result2 == "null") {
                            mlog("重载")
                            webView.reload()
                        }
                    }
                }, 500)
            }
        }
    }
    
    /**
     * 在历史记录更新时调用
     * 
     * 用于在用户导航（前进/后退）后更新导航状态
     */
    override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) {
        super.doUpdateVisitedHistory(view, url, isReload)
        // 更新导航状态
        state.coroutine?.launch {
            state.更新导航状态()
        }
    }


    /**
     * 拦截资源请求
     * 
     * 在 WebView 请求任何资源（图片、JS、CSS 等）前调用
     * 可用于修改请求、提供本地资源或阻止某些请求
     */
    override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest)
        : WebResourceResponse? {
        val url = request.url.toString()
        替换本地资源文件(url)?.let {
            mlog("替换文件",url)
            return it
        }

        // 是否被拦截
        return if (!state.响应可否加载文件(url,request.requestHeaders)) {
            mlog("被拦截",url)
            WebResourceResponse(null, null, null)
        }else{
            super.shouldInterceptRequest(view, request)
        }
    }

    override fun onLoadResource(view: WebView?, url: String?) {
        super.onLoadResource(view, url)
        // 加载资源?
    }

    /**
     * 获取本地资源文件
     * 
     * 尝试从本地缓存或 assets 目录获取资源，用于加速加载或离线浏览
     */
    private fun 替换本地资源文件(url: String): WebResourceResponse? {
        if (url.isEmpty()) return null

        // 获取本地缓存  拦截图片 mWeb.enableNoPicMode() 多做判断，无益
        val value = 取本地替代资源(url) ?: return null
        mlog("取本地替代",value,url)
        val qs = value.substring(0, 2)

        return when (qs) {
            // assets
            "as" -> getWebResourceResponse(value.substring(3),"text/javascript")

            // assets css
            "ax" -> getWebResourceResponse(value.substring(3),"text/css")

            // null
            "nt" -> WebResourceResponse(null, null, null)
            else -> null
        }
    }

    /**
     * 替换本地资源
     */
    fun 取本地替代资源(url: String): String? {
        val hosturl: String = 地址操作.取完整主机名(url)
        // 内置谷歌文件包 也是assets中文件
        if (hosturl.contains("google") || hosturl.contains("gstatic.com")) {
            val googleList = arrayOf(
                "translate.google.com",
                "translate.googleapis.com",
                "www.google.com",
                "www.gstatic.com",
                "translate-pa.googleapis.com"
            )
            var url2 = url
            for (s in googleList) {
                if (s == hosturl) {
                    if (url2.contains("?")) url2 = url2.left("?") ?: ""
                    val path = "google/" + s + url2.right(s)
                    return "as:$path"
                }
            }



        }
        return null
    }


    /**
     * 创建 WebResourceResponse 对象
     * 
     * 从 assets 目录读取资源并创建相应的 WebResourceResponse
     */
    private fun getWebResourceResponse(url: String,type : String): WebResourceResponse? {
        var res: WebResourceResponse? = null
        try {
            val instream: InputStream = Utils.getApp().baseContext.getResources().getAssets().open(url)
            res = WebResourceResponse(type, "UTF-8", instream)
        } catch (e: Exception) {
            // e.printStackTrace();
        }
        return res
    }


    /*
    // 接收到资源加载错误时调用
    override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) {
        App.log("onReceivedError",request?.requestHeaders,request?.url,error.toString())

        super.onReceivedError(view, request, error)
    }
    
    // 接收到 HTTP 错误时调用（如 404、500 等）
    override fun onReceivedHttpError(
        view: WebView?,
        request: WebResourceRequest?,
        errorResponse: WebResourceResponse?
    ) {
        App.log("onReceivedHttpError",request?.requestHeaders,request?.url)
        super.onReceivedHttpError(view, request, errorResponse)
    }*/


    /**
     * 处理表单重新提交
     * 
     * 当用户在已提交表单的页面上点击刷新或返回按钮时调用
     * 用于防止重复提交表单数据
     */
    override fun onFormResubmission(view: WebView?, dontResend: Message?, resend: Message?) {
        // dontResend.sendToTarget();
        super.onFormResubmission(view, dontResend, resend)
    }

    /**
     * 处理 HTTP 认证请求
     * 
     * 当网站需要 HTTP 基本认证或摘要认证时调用
     * 显示登录对话框让用户输入用户名和密码
     */
    override fun onReceivedHttpAuthRequest(view: WebView?, handler: HttpAuthHandler, host: String?, realm: String?) {
        ActivityUtils.getTopActivity().let { ctx ->
            val usernameInput = EditText(ctx)
            usernameInput.hint = "名称"
            val passwordInput = EditText(ctx)
            passwordInput.hint = "密码"
            passwordInput.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
            val ll = LinearLayout(ctx)
            ll.orientation = LinearLayout.VERTICAL
            ll.addView(usernameInput)
            ll.addView(passwordInput)
            val authDialog = AlertDialog.Builder(ctx)
                .setTitle("登录")
                .setView(ll)
                .setCancelable(false)
                .setPositiveButton("确定") { dialog, whichButton ->
                    handler.proceed(usernameInput.text.toString(), passwordInput.text.toString())
                    dialog.dismiss()
                }
                .setNegativeButton("取消") { dialog, whichButton ->
                    dialog.dismiss()
                    view!!.stopLoading()
                }
            if (view != null) authDialog.show()
        }
    }

    /**
     * 接收到登录请求时调用
     * 
     * 处理网站的自动登录请求
     */
    override fun onReceivedLoginRequest(var1: WebView?, var2: String?, var3: String?, var4: String?) {
        super.onReceivedLoginRequest(var1, var2, var3, var4)
    }

    /**
     * 处理 SSL 证书错误
     * 
     * 当 HTTPS 连接的证书有问题时调用
     * 可以选择继续加载（不安全）或取消加载
     */
    var enableSSLSafeCheup = false
    override fun onReceivedSslError(webView: WebView?, handler: SslErrorHandler, sslError: SslError?) {
        if (!enableSSLSafeCheup) handler.proceed()
        else handler.cancel()
    }


}